using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
using System.Xml;
using System.Threading;
using Microsoft.Win32;
using Ares.Crypt;
using Ares.Protocols;
using Ares.CommonObjects;
using System.Drawing;
using System.Drawing.Imaging;

namespace cb0tServer
{
    class CoreSettings
    {
        private static Mutex mutex = new Mutex();

        public static bool link_any;
        public static String room_bot;
        public static String room_location;
        public static String room_name;
        public static String pm_reply;
        public static ushort room_port;
        public static ushort scas_version;
        public static IPAddress room_local_ip;
        public static IPAddress room_external_ip;

        public static IPAddress additional_host;
        public static String additional_host_pass;

        public static bool allow_linking;
        public static bool allow_linked_admins;
        public static bool chat_logging;

        public static IPAddress UDPAddress;

        public static bool allow_audio;
        public static bool allow_video;
        public static bool allow_images;
        public static bool allow_documents;
        public static bool allow_software;
        public static bool allow_other;

        public static bool avatars;

        public static byte room_language;

        public static byte min_age_value;
        public static bool min_age_enabled;
        public static int dint = 5;

        public static bool show_on_list;
        public static bool let_save;

        public static String last_quiz;
        public static int clear_ban_interval;
        public static bool clear_ban_enabled;

        public static bool gender_allow_male;
        public static bool gender_allow_female;
        public static bool gender_allow_unknown;
        public static bool can_vc;
        public static bool can_dc_old;
        public static bool can_dc;
        public static bool supports_custom_emoticons;
        public static bool can_all_scribble;

        public static bool captcha;

        private static Random rnd = new Random();

        private static Color GetColor
        {
            get
            {
                return Color.FromArgb(rnd.Next(0, int.MaxValue));
            }
        }

        public static byte[] default_avatar
        {
            get
            {
                if (Avatar.default_av_bytes != null)
                    return Avatar.default_av_bytes;

                Bitmap b = new Bitmap(48, 48);

                for (int x = 0; x < 48; x++)
                    for (int y = 0; y < 48; y++)
                        b.SetPixel(x, y, GetColor);

                Graphics g = Graphics.FromImage(b);
                g.DrawImage(new Bitmap(new MemoryStream(AresLogo)), new Point(1, 1));
                MemoryStream ms = new MemoryStream();
                b.Save(ms, ImageFormat.Jpeg);
                return ms.ToArray();
            }
        }

        private static IPAddress GenerateLocalIP()
        {
            byte[] octs = new byte[4];
            
            for (int i = 0; i < octs.Length; i++)
                octs[i] = (byte)rnd.Next(0, 255);

            return new IPAddress(octs);
        }

        public static String GetUDPRoomName()
        {
            String str = room_name;

            while (Encoding.UTF8.GetByteCount(str) > 30)
                str = str.Substring(0, str.Length - 1);

            return str;
        }

        public static String BuildHashlinkForWebsite()
        {
            if (room_external_ip.Equals(IPAddress.Parse("0.0.0.0"))) return null;

            ChannelListItem c = new ChannelListItem();
            c.name = room_name;
            c.localIp = room_local_ip;
            c.port = room_port;
            c.externalIp = room_external_ip;

            return Hashlinks.EncodeHashlink(c);
        }

        public static void Load()
        {
            let_save = false;
            link_any = false;
            allow_linking = true;
            allow_linked_admins = false;
            chat_logging = false;
            room_bot = "Server";
            room_location = "Pending...";
            room_local_ip = GenerateLocalIP();
            room_external_ip = IPAddress.Parse("0.0.0.0");

            additional_host = IPAddress.Parse("127.0.0.1");
            additional_host_pass = "";

            pm_reply = "Welcome to sb0t, +n. :-)";
            room_name = "My sb0t";
            room_port = (ushort)rnd.Next(0, 65535);
            scas_version = 1000;

            room_language = 5;

            UDPAddress = IPAddress.Any;

            allow_audio = true;
            allow_documents = true;
            allow_images = true;
            allow_other = true;
            allow_software = true;
            allow_video = true;

            avatars = true;

            min_age_value = 18;
            min_age_enabled = false;
            show_on_list = true;
            last_quiz = "";
            clear_ban_interval = 24;
            clear_ban_enabled = false;

            gender_allow_male = true;
            gender_allow_female = true;
            gender_allow_unknown = true;
            can_vc = false;
            can_dc_old = false;
            can_dc = true;

            supports_custom_emoticons = true;
            captcha = true;
            can_all_scribble = false;

            if (File.Exists(sb0t_winGUI.RunOnceFileUpdater.sbotpath + "data/core.xml"))
            {
                try
                {
                    FileStream f = new FileStream(sb0t_winGUI.RunOnceFileUpdater.sbotpath + "data/core.xml", FileMode.Open);
                    XmlReader xml = XmlReader.Create(new StreamReader(f));

                    xml.MoveToContent();
                    xml.ReadSubtree().ReadToFollowing("core");
                    xml.ReadToFollowing("details");
                    xml.ReadSubtree().ReadToFollowing("name");
                    room_name = Encoding.UTF8.GetString(Convert.FromBase64String(xml.ReadElementContentAsString()));
                    xml.ReadToFollowing("pm");
                    pm_reply = Encoding.UTF8.GetString(Convert.FromBase64String(xml.ReadElementContentAsString()));
                    xml.ReadToFollowing("port");
                    room_port = ushort.Parse(xml.ReadElementContentAsString());
                    xml.ReadToFollowing("host");
                    additional_host = new IPAddress(Convert.FromBase64String(xml.ReadElementContentAsString()));
                    xml.ReadToFollowing("hostpass");
                    additional_host_pass = Encoding.UTF8.GetString(Convert.FromBase64String(xml.ReadElementContentAsString()));

                    xml.Close();
                    f.Flush();
                    f.Close();
                }
                catch { }
            }

            if (File.Exists(sb0t_winGUI.RunOnceFileUpdater.sbotpath + "data/var.xml"))
            {
                try
                {
                    FileStream f = new FileStream(sb0t_winGUI.RunOnceFileUpdater.sbotpath + "data/var.xml", FileMode.Open);
                    XmlReader xml = XmlReader.Create(new StreamReader(f));

                    xml.MoveToContent();
                    xml.ReadSubtree().ReadToFollowing("core");
                    xml.ReadToFollowing("details");
                    xml.ReadSubtree().ReadToFollowing("bot");
                    room_bot = Encoding.UTF8.GetString(Convert.FromBase64String(xml.ReadElementContentAsString()));
                    xml.ReadToFollowing("location");
                    room_location = Encoding.UTF8.GetString(Convert.FromBase64String(xml.ReadElementContentAsString()));
                    xml.ReadToFollowing("ext");
                    room_external_ip = new IPAddress(Convert.FromBase64String(xml.ReadElementContentAsString()));
                    xml.ReadToFollowing("link");
                    allow_linking = bool.Parse(xml.ReadElementContentAsString());
                    xml.ReadToFollowing("linkadmins");
                    allow_linked_admins = bool.Parse(xml.ReadElementContentAsString());
                    xml.ReadToFollowing("logging");
                    chat_logging = bool.Parse(xml.ReadElementContentAsString());
                    xml.ReadToFollowing("language");
                    room_language = byte.Parse(xml.ReadElementContentAsString());
                    xml.ReadToFollowing("audio");
                    allow_audio = bool.Parse(xml.ReadElementContentAsString());
                    xml.ReadToFollowing("video");
                    allow_video = bool.Parse(xml.ReadElementContentAsString());
                    xml.ReadToFollowing("image");
                    allow_images = bool.Parse(xml.ReadElementContentAsString());
                    xml.ReadToFollowing("document");
                    allow_documents = bool.Parse(xml.ReadElementContentAsString());
                    xml.ReadToFollowing("software");
                    allow_software = bool.Parse(xml.ReadElementContentAsString());
                    xml.ReadToFollowing("other");
                    allow_other = bool.Parse(xml.ReadElementContentAsString());
                    xml.ReadToFollowing("udp");
                    UDPAddress = new IPAddress(Convert.FromBase64String(xml.ReadElementContentAsString()));
                    xml.ReadToFollowing("avatars");
                    avatars = bool.Parse(xml.ReadElementContentAsString());
                    xml.ReadToFollowing("min_age_value");
                    min_age_value = byte.Parse(xml.ReadElementContentAsString());
                    xml.ReadToFollowing("min_age_enabled");
                    min_age_enabled = bool.Parse(xml.ReadElementContentAsString());
                    xml.ReadToFollowing("dint");
                    dint = int.Parse(xml.ReadElementContentAsString());
                    xml.ReadToFollowing("show_on_list");
                    show_on_list = bool.Parse(xml.ReadElementContentAsString());
                    xml.ReadToFollowing("last_quiz");
                    last_quiz = Encoding.UTF8.GetString(Convert.FromBase64String(xml.ReadElementContentAsString()));
                    xml.ReadToFollowing("clear_ban_interval");
                    clear_ban_interval = int.Parse(xml.ReadElementContentAsString());
                    xml.ReadToFollowing("clear_ban_enabled");
                    clear_ban_enabled = bool.Parse(xml.ReadElementContentAsString());
                    xml.ReadToFollowing("gender_allow_male");
                    gender_allow_male = bool.Parse(xml.ReadElementContentAsString());
                    xml.ReadToFollowing("gender_allow_female");
                    gender_allow_female = bool.Parse(xml.ReadElementContentAsString());
                    xml.ReadToFollowing("gender_allow_unknown");
                    gender_allow_unknown = bool.Parse(xml.ReadElementContentAsString());
                    xml.ReadToFollowing("can_vc");
                    can_vc = bool.Parse(xml.ReadElementContentAsString());
                    xml.ReadToFollowing("can_dc");
                    can_dc_old = bool.Parse(xml.ReadElementContentAsString());
                    xml.ReadToFollowing("can_dc2");
                    can_dc = bool.Parse(xml.ReadElementContentAsString());
                    xml.ReadToFollowing("supports_custom_emoticons");
                    supports_custom_emoticons = bool.Parse(xml.ReadElementContentAsString());
                    xml.ReadToFollowing("captcha");
                    captcha = bool.Parse(xml.ReadElementContentAsString());
                    xml.ReadToFollowing("can_all_scribble");
                    can_all_scribble = bool.Parse(xml.ReadElementContentAsString());
                    
                    xml.Close();
                    f.Flush();
                    f.Close();
                }
                catch { }
            }

            if (File.Exists(sb0t_winGUI.RunOnceFileUpdater.sbotpath + "data/linkany.xml"))
            {
                try
                {
                    FileStream f = new FileStream(sb0t_winGUI.RunOnceFileUpdater.sbotpath + "data/linkany.xml", FileMode.Open);
                    XmlReader xml = XmlReader.Create(new StreamReader(f));

                    xml.MoveToContent();
                    xml.ReadSubtree().ReadToFollowing("core");
                    xml.ReadToFollowing("details");
                    xml.ReadSubtree().ReadToFollowing("linkany");
                    link_any = bool.Parse(xml.ReadElementContentAsString());

                    xml.Close();
                    f.Flush();
                    f.Close();
                }
                catch { }
            }
        }

        public static void Save()
        {
            if (!let_save)
                return;

            mutex.WaitOne();

            try
            {
                XmlWriterSettings appearance = new XmlWriterSettings();
                appearance.Indent = true;
                XmlWriter xml = XmlWriter.Create(sb0t_winGUI.RunOnceFileUpdater.sbotpath + "data/core.xml", appearance);

                xml.WriteStartDocument();
                xml.WriteStartElement("core");
                xml.WriteStartElement("details");
                xml.WriteElementString("name", Convert.ToBase64String(Encoding.UTF8.GetBytes(room_name)));
                xml.WriteElementString("pm", Convert.ToBase64String(Encoding.UTF8.GetBytes(pm_reply)));
                xml.WriteElementString("port", room_port.ToString());
                xml.WriteElementString("host", Convert.ToBase64String(additional_host.GetAddressBytes()));
                xml.WriteElementString("hostpass", Convert.ToBase64String(Encoding.UTF8.GetBytes(additional_host_pass)));
                xml.WriteEndElement();
                xml.WriteEndElement();
                xml.WriteEndDocument();
                xml.Flush();
                xml.Close();
            }
            catch { }

            mutex.ReleaseMutex();
        }

        public static void SaveNew()
        {
            if (!let_save)
                return;

            try
            {
                XmlWriterSettings appearance = new XmlWriterSettings();
                appearance.Indent = true;
                XmlWriter xml = XmlWriter.Create(sb0t_winGUI.RunOnceFileUpdater.sbotpath + "data/var.xml", appearance);

                xml.WriteStartDocument();
                xml.WriteStartElement("core");
                xml.WriteStartElement("details");
                xml.WriteElementString("bot", Convert.ToBase64String(Encoding.UTF8.GetBytes(room_bot)));
                xml.WriteElementString("location", Convert.ToBase64String(Encoding.UTF8.GetBytes(room_location)));
                xml.WriteElementString("ext", Convert.ToBase64String(room_external_ip.GetAddressBytes()));
                xml.WriteElementString("link", allow_linking.ToString());
                xml.WriteElementString("linkadmins", allow_linked_admins.ToString());
                xml.WriteElementString("logging", chat_logging.ToString());
                xml.WriteElementString("language", room_language.ToString());
                xml.WriteElementString("audio", allow_audio.ToString());
                xml.WriteElementString("video", allow_video.ToString());
                xml.WriteElementString("image", allow_images.ToString());
                xml.WriteElementString("document", allow_documents.ToString());
                xml.WriteElementString("software", allow_software.ToString());
                xml.WriteElementString("other", allow_other.ToString());
                xml.WriteElementString("udp", Convert.ToBase64String(UDPAddress.GetAddressBytes()));
                xml.WriteElementString("avatars", avatars.ToString());
                xml.WriteElementString("min_age_value", min_age_value.ToString());
                xml.WriteElementString("min_age_enabled", min_age_enabled.ToString());
                xml.WriteElementString("dint", dint.ToString());
                xml.WriteElementString("show_on_list", show_on_list.ToString());
                xml.WriteElementString("last_quiz", Convert.ToBase64String(Encoding.UTF8.GetBytes(last_quiz)));
                xml.WriteElementString("clear_ban_interval", clear_ban_interval.ToString());
                xml.WriteElementString("clear_ban_enabled", clear_ban_enabled.ToString());
                xml.WriteElementString("gender_allow_male", gender_allow_male.ToString());
                xml.WriteElementString("gender_allow_female", gender_allow_female.ToString());
                xml.WriteElementString("gender_allow_unknown", gender_allow_unknown.ToString());
                xml.WriteElementString("can_vc", can_vc.ToString());
                xml.WriteElementString("can_dc", can_dc_old.ToString());
                xml.WriteElementString("can_dc2", can_dc.ToString());
                xml.WriteElementString("supports_custom_emoticons", supports_custom_emoticons.ToString());
                xml.WriteElementString("captcha", captcha.ToString());
                xml.WriteElementString("can_all_scribble", can_all_scribble.ToString());

                xml.WriteEndElement();
                xml.WriteEndElement();
                xml.WriteEndDocument();
                xml.Flush();
                xml.Close();
            }
            catch { }
        }

        public static void SaveLinkAny()
        {
            try
            {
                XmlWriterSettings appearance = new XmlWriterSettings();
                appearance.Indent = true;
                XmlWriter xml = XmlWriter.Create(sb0t_winGUI.RunOnceFileUpdater.sbotpath + "data/linkany.xml", appearance);

                xml.WriteStartDocument();
                xml.WriteStartElement("core");
                xml.WriteStartElement("details");
                xml.WriteElementString("linkany", link_any.ToString());
                xml.WriteEndElement();
                xml.WriteEndElement();
                xml.WriteEndDocument();
                xml.Flush();
                xml.Close();
            }
            catch { }
        }

        private static byte[] AresLogo = new byte[]
        {
            66, 77, 38, 4, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 40, 0, 0, 0, 18,
            0, 0, 0, 18, 0, 0, 0, 1, 0, 24, 0, 0, 0, 0, 0, 240, 3, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252, 252, 252, 252,
            252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252,
            252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252,
            252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252,
            252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 0, 0,
            252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252,
            252, 252, 229, 229, 229, 144, 144, 144, 222, 181, 138, 237, 187,
            134, 239, 189, 135, 228, 183, 136, 221, 192, 165, 219, 219, 219,
            252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252,
            252, 252, 0, 0, 252, 252, 252, 251, 251, 251, 192, 192, 192,
            162, 162, 162, 126, 126, 126, 213, 127, 74, 253, 193, 130, 239,
            153, 92, 228, 151, 93, 228, 150, 91, 249, 192, 130, 255, 210,
            146, 222, 132, 73, 207, 150, 126, 161, 161, 161, 210, 210, 210,
            252, 252, 252, 252, 252, 252, 0, 0, 252, 252, 252, 250, 250,
            250, 109, 109, 109, 9, 45, 41, 13, 47, 46, 107, 63, 32, 255,
            194, 124, 120, 71, 34, 11, 37, 36, 14, 32, 26, 204, 131, 67,
            249, 178, 109, 55, 43, 27, 13, 55, 54, 29, 47, 38, 160, 160,
            160, 252, 252, 252, 252, 252, 252, 0, 0, 252, 252, 252, 252,
            252, 252, 208, 154, 132, 52, 91, 78, 0, 111, 113, 23, 48, 41,
            243, 116, 30, 117, 86, 41, 0, 84, 91, 0, 64, 65, 207, 120, 52,
            193, 98, 29, 0, 80, 80, 0, 142, 145, 101, 83, 56, 226, 172,
            137, 252, 252, 252, 252, 252, 252, 0, 0, 252, 252, 252, 222,
            222, 222, 206, 129, 71, 141, 91, 56, 5, 157, 157, 0, 77, 79,
            165, 69, 3, 147, 87, 35, 49, 104, 108, 43, 73, 69, 211, 107,
            16, 108, 70, 25, 0, 156, 158, 22, 153, 150, 192, 108, 55, 239,
            167, 96, 206, 206, 206, 252, 252, 252, 0, 0, 252, 252, 252, 200,
            177, 155, 217, 146, 80, 206, 105, 48, 39, 130, 123, 0, 123, 126,
            73, 63, 33, 228, 106, 18, 221, 129, 40, 219, 122, 31, 215, 95,
            10, 25, 81, 69, 2, 189, 189, 71, 94, 76, 235, 140, 66, 248, 189,
            112, 208, 172, 138, 252, 252, 252, 0, 0, 252, 252, 252, 169,
            130, 95, 218, 159, 89, 228, 110, 46, 83, 81, 70, 2, 151, 150,
            8, 63, 59, 209, 95, 12, 255, 186, 92, 255, 218, 158, 149, 70,
            15, 0, 119, 117, 14, 175, 174, 125, 71, 37, 245, 103, 24, 238,
            182, 105, 195, 146, 99, 252, 252, 252, 0, 0, 252, 252, 252, 156,
            108, 68, 213, 178, 103, 211, 69, 36, 128, 40, 22, 13, 160, 156,
            0, 89, 89, 118, 50, 8, 255, 138, 40, 247, 137, 64, 64, 53, 31,
            1, 169, 168, 31, 144, 138, 179, 53, 9, 242, 64, 3, 218, 156, 85,
            184, 135, 85, 252, 252, 252, 0, 0, 252, 252, 252, 163, 118, 69,
            184, 179, 128, 204, 79, 56, 197, 46, 0, 38, 134, 124, 0, 134,
            133, 43, 40, 27, 238, 93, 7, 203, 71, 0, 10, 85, 81, 2, 191,
            190, 79, 100, 76, 215, 55, 0, 230, 66, 19, 197, 142, 84, 167,
            120, 73, 252, 252, 252, 0, 0, 252, 252, 252, 169, 137, 95, 165,
            176, 152, 226, 155, 146, 247, 85, 19, 102, 106, 82, 0, 160, 159,
            2, 65, 64, 190, 68, 10, 128, 55, 17, 0, 142, 141, 11, 174, 172,
            146, 76, 31, 254, 92, 8, 239, 118, 76, 199, 171, 139, 157, 115,
            76, 252, 252, 252, 0, 0, 252, 252, 252, 194, 172, 147, 176, 181,
            167, 231, 220, 226, 255, 129, 102, 178, 85, 45, 13, 155, 152, 0,
            105, 104, 91, 54, 31, 56, 73, 58, 2, 182, 180, 37, 130, 120, 222,
            109, 57, 255, 128, 85, 234, 182, 166, 212, 197, 177, 172, 143,
            116, 252, 252, 252, 0, 0, 252, 252, 252, 211, 211, 211, 179, 176,
            159, 241, 249, 252, 246, 201, 203, 234, 105, 77, 52, 126, 115, 0,
            141, 140, 8, 50, 47, 3, 93, 90, 0, 187, 185, 98, 107, 88, 251, 161,
            134, 247, 188, 180, 239, 231, 221, 218, 201, 186, 192, 192, 192,
            252, 252, 252, 0, 0, 252, 252, 252, 252, 252, 252, 202, 195, 175,
            249, 251, 253, 248, 254, 255, 252, 195, 189, 119, 101, 84, 0, 161,
            161, 0, 130, 128, 0, 173, 170, 4, 162, 159, 167, 105, 83, 255, 206,
            198, 245, 236, 227, 253, 247, 241, 207, 191, 175, 252, 252, 252,
            252, 252, 252, 0, 0, 252, 252, 252, 252, 252, 252, 247, 247, 247,
            213, 211, 199, 255, 255, 255, 255, 255, 255, 189, 128, 111, 34,
            137, 134, 34, 209, 209, 22, 190, 189, 48, 100, 93, 227, 160, 140,
            255, 255, 251, 255, 251, 247, 232, 224, 216, 239, 239, 239, 252,
            252, 252, 252, 252, 252, 0, 0, 252, 252, 252, 252, 252, 252, 252,
            252, 252, 250, 250, 250, 237, 236, 229, 249, 251, 248, 239, 194,
            182, 127, 103, 90, 118, 136, 129, 99, 116, 110, 144, 97, 79, 254,
            228, 218, 248, 247, 244, 238, 232, 226, 242, 242, 242, 252, 252,
            252, 252, 252, 252, 252, 252, 252, 0, 0, 252, 252, 252, 252, 252,
            252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 219, 219, 219,
            237, 229, 220, 229, 185, 169, 231, 175, 158, 228, 173, 156, 222,
            181, 168, 233, 228, 223, 210, 210, 210, 252, 252, 252, 252, 252,
            252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 0, 0, 252, 252,
            252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252,
            252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252,
            252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252,
            252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252,
            0, 0
        };
    }
}
